#include "svdpi.h"
#include "switchboard.hpp"
#include <stdio.h>
#include <fstream>
#include <iostream>

#define NBYTES 4

extern "C" void hello() 
{
    printf("hello world\n");
}


// translate SbPacket to AXIPakcet
extern "C" int receive_requset_from_sb(uint32_t *rev_data, uint32_t *rev_addr, uint32_t *operate)
{
    SBRX rx;
    sb_packet rxp;
    rx.init("from_sb_to_axil.q");
    //rx.recv_blocking(rxp);
    bool success = rx.recv(rxp);
    if (!success) {
        printf("DPI: No receive\n");

        *rev_addr = 0xffffffff;
        *rev_data = 0xffffffff;
        *operate = 0x0;
        return 0; //invalid
    } else {
        printf("DPI: receive packet: %s\n", sb_packet_to_str(rxp, NBYTES).c_str());
        uint32_t addr = rxp.destination;
        uint32_t data = static_cast<uint32_t>(rxp.data[0]);
        data = data << 8 | static_cast<uint32_t>(rxp.data[1]);
        data = data << 8 | static_cast<uint32_t>(rxp.data[2]);
        data = data << 8 | static_cast<uint32_t>(rxp.data[3]);
        uint32_t op = static_cast<uint32_t>(rxp.data[4]);

        *rev_addr = addr;
        *rev_data = data;
        *operate = op; // 0:read 1:write
        return 1; //valid
    }
    return 0;
}

extern "C" int send_response_to_sb(uint32_t send_data, uint32_t send_addr, uint32_t resp_valid)
{
    SBTX tx;
    sb_packet txp;
    tx.init("from_axil_to_sb.q");
    txp.destination = send_addr;
    txp.last = true;
    txp.data[0] = static_cast<uint8_t>(send_data >> 24);
    txp.data[1] = static_cast<uint8_t>(send_data >> 16);
    txp.data[2] = static_cast<uint8_t>(send_data >> 8);
    txp.data[3] = static_cast<uint8_t>(send_data >> 0);
    txp.data[4] = static_cast<uint8_t>(resp_valid);
    tx.send_blocking(txp);
    printf("DPI: send packet: %s\n", sb_packet_to_str(txp, NBYTES).c_str());
    return 1;
}